package com.example.demo.modules.user.service.impl;

import com.example.demo.modules.user.dto.UserDTO;
import com.example.demo.modules.user.entity.User;
import com.example.demo.modules.user.repository.UserRepository;
import com.example.demo.modules.user.service.UserService;
import com.example.demo.modules.user.exception.UserNotFoundException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    /**
     * 查找所有用户
     */
    @Override
    public List<UserDTO> findAll() {
        return userRepository.findAll().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 根据ID查找用户
     */
    @Override
    public UserDTO findById(Long id) {
        return userRepository.findById(id)
                .map(this::convertToDTO)
                .orElseThrow(() -> new UserNotFoundException("用户不存在: ID " + id));
    }
    
    /**
     * 保存新用户
     */
    @Override
    @Transactional
    public UserDTO save(UserDTO userDTO) {
        // 验证用户名唯一性
        if (userRepository.existsByUsername(userDTO.getUsername())) {
            throw new IllegalArgumentException("用户名已存在");
        }
        
        // 验证邮箱唯一性
        if (userRepository.existsByEmail(userDTO.getEmail())) {
            throw new IllegalArgumentException("邮箱已存在");
        }
        
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        
        // 加密密码
        if (userDTO.getPassword() != null && !userDTO.getPassword().isEmpty()) {
            user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        }
        
        User savedUser = userRepository.save(user);
        return convertToDTO(savedUser);
    }
    
    /**
     * 更新现有用户
     */
    @Override
    @Transactional
    public UserDTO update(UserDTO userDTO) {
        User existingUser = userRepository.findById(userDTO.getId())
                .orElseThrow(() -> new UserNotFoundException("用户不存在: ID " + userDTO.getId()));
        
        // 验证用户名唯一性（排除自身）
        if (!existingUser.getUsername().equals(userDTO.getUsername()) && 
                userRepository.existsByUsername(userDTO.getUsername())) {
            throw new IllegalArgumentException("用户名已存在");
        }
        
        // 验证邮箱唯一性（排除自身）
        if (!existingUser.getEmail().equals(userDTO.getEmail()) && 
                userRepository.existsByEmail(userDTO.getEmail())) {
            throw new IllegalArgumentException("邮箱已存在");
        }
        
        // 仅复制非空字段，避免覆盖现有数据
        if (userDTO.getUsername() != null) existingUser.setUsername(userDTO.getUsername());
        if (userDTO.getEmail() != null) existingUser.setEmail(userDTO.getEmail());
        if (userDTO.getFullName() != null) existingUser.setFullName(userDTO.getFullName());
        if (userDTO.getAvatar() != null) existingUser.setAvatar(userDTO.getAvatar());
        existingUser.setEnabled(userDTO.isEnabled());
        if (userDTO.getRole() != null) existingUser.setRole(userDTO.getRole());
        
        // 如果提供了新密码，则更新密码
        if (userDTO.getPassword() != null && !userDTO.getPassword().isEmpty()) {
            existingUser.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        }
        
        User updatedUser = userRepository.save(existingUser);
        return convertToDTO(updatedUser);
    }
    
    /**
     * 删除用户
     */
    @Override
    @Transactional
    public void delete(Long id) {
        if (!userRepository.existsById(id)) {
            throw new UserNotFoundException("用户不存在: ID " + id);
        }
        userRepository.deleteById(id);
    }
    
    /**
     * 根据关键词搜索用户
     */
    @Override
    public List<UserDTO> search(String keyword) {
        if (keyword == null || keyword.isEmpty()) {
            return findAll();
        }
        
        return userRepository.search(keyword).stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 将实体转换为DTO
     */
    private UserDTO convertToDTO(User user) {
        UserDTO dto = new UserDTO();
        BeanUtils.copyProperties(user, dto);
        // 不传输密码
        dto.setPassword(null);
        return dto;
    }
} 